/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mbean;

import java.io.IOException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.ServletException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.omnifaces.util.Faces;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author dingnangen
 */
@Named(value = "shiroMB")
@SessionScoped
public class shiroMB implements Serializable {

    private String username, password;
    private Subject subject = SecurityUtils.getSubject();
    private UsernamePasswordToken token;
    private static final Logger log = LoggerFactory.getLogger(shiroMB.class);
    @Inject
    private MenuMB menuMB;

    /**
     * Creates a new instance of shiroMB
     */
    public shiroMB() {
    }

    public void login() throws IOException, ServletException {
        try {
            System.out.println("Faces.getRequestBaseURL():" + Faces.getRequestBaseURL());
            System.out.println("Faces.getRequestURL():" + Faces.getRequestURL());
            System.out.println("Faces.getRequestURI():" + Faces.getRequestURI());
            //System.out.println(WebUtils.getSavedRequest(JsfUtil.getRequest()).getRequestUrl());

            username = username.trim();
            password = password.trim();
            token = new UsernamePasswordToken(username, password);

            subject = SecurityUtils.getSubject();
            subject.login(token);
            // leftTreeMB.setBool(false);

            SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
            if (savedRequest != null) {
                System.out.println("savedRequest():" + savedRequest.getRequestUrl());
            }
            System.out.println("role:V" + subject.isPermitted("role:V"));
            System.out.println("admin" + subject.hasRole("admin"));
            System.out.println("subject.getPrincipal():" + subject.getPrincipal().getClass());
            System.out.println("FacesContext.getCurrentInstance().getExternalContext()" + FacesContext.getCurrentInstance().getExternalContext().getClass());
            //          FacesContext.getCurrentInstance().getExternalContext().redirect(savedRequest != null ? savedRequest.getRequestUrl() : "/Army/faces/admin/index.xhtml");
            Faces.redirect(savedRequest != null ? savedRequest.getRequestUrl() : "/distributionSystem-war/faces/admin/index.xhtml");
            //return (savedRequest != null ? savedRequest.getRequestUrl().substring(11) : "/admin/index?faces-redirect=true");

            //return "/admin/index?faces-redirect=true";
        } catch (Exception e) {

            log.trace("ceshi" + username);
            System.out.println("ShiroMB.login=" + e.toString());
            System.out.println("ShiroMB.username=" + username);
            System.out.println("ShiroMB.pw=" + password);
            System.out.println("ShiroMB.token=" + token);
            System.out.println("subject.getPrincipal():" + subject.getPrincipal());
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("loginfail", "用户名或密码错误!");
            // Faces.redirect( "/ProjectModel/faces/admin/index.xhtml");
            // Faces.getRequest().getRequestDispatcher("faces/admin/index.xhtml").forward(Faces.getRequest(), Faces.getResponse());
            // FacesContext.getCurrentInstance().getExternalContext().dispatch("faces/admin/index.xhtml");

            //return "/admin/index";
        }
    }

    public void logout() throws IOException {
        subject = SecurityUtils.getSubject();
        subject.logout();

        Faces.redirect("/distributionSystem-war/faces/login.xhtml");
    }

    public void redirectIndexUrl() throws IOException {
        Faces.redirect("/distributionSystem-war/faces/admin/index.xhtml");
    }

    protected void clearCache(String principal) {
        System.out.println("clearCache");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();

        try {
            if (userRealm.getAuthenticationCache().get(principal) != null) {
                userRealm.getAuthorizationCache().remove(userRealm.getAuthenticationCache().get(principal).getPrincipals());
            }
            userRealm.getAuthenticationCache().remove(principal);
            menuMB.setMenus(null);

            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());
        } catch (Exception e) {
            System.out.println("清除权限失败:" + e);
        }
    }

    public void clearCachedAuthorizationInfo() {
        System.out.println("######");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();
//        System.out.println("getPrincipal:" + SecurityUtils.getSubject().getPrincipal() + "#isCachingEnabled:" + userRealm.isCachingEnabled() + "#isAuthenticationCachingEnabled:" + userRealm.isAuthenticationCachingEnabled()
//                + "#isAuthorizationCachingEnabled:" + userRealm.isAuthorizationCachingEnabled() );
        try {
            System.out.println("getPrincipal:" + SecurityUtils.getSubject().getPrincipal() + "#isCachingEnabled:" + userRealm.isCachingEnabled() + "#isAuthenticationCachingEnabled:" + userRealm.isAuthenticationCachingEnabled()
                    + "#isAuthorizationCachingEnabled:" + userRealm.isAuthorizationCachingEnabled()
                    + "#Cache:" + (userRealm.getAuthenticationCache().get(
                            SecurityUtils.getSubject().getPrincipal())));

            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());
            Set s = userRealm.getAuthorizationCache().keys();
            Collection<AuthorizationInfo> values = userRealm.getAuthorizationCache().values();
            Set<Object> keys = userRealm.getAuthenticationCache().keys();
            Collection<AuthenticationInfo> values1 = userRealm.getAuthenticationCache().values();
            System.out.println("s:" + s + "#values:" + values + "#s:" + keys + "#values:" + values1);
            subject = SecurityUtils.getSubject();
            System.out.println("isPermitted:" + subject.isPermitted("role:D,"));
            System.out.println("isPermitted:" + subject.isPermitted("2:Q,V,E,"));
            System.out.println("isPermitted:" + subject.isPermitted("3:Q,V,E,"));
            for (Object v : userRealm.getAuthorizationCache().keys()) {
                System.out.println("keys:" + v.toString());
            }
            ;
        } catch (Exception e) {
            System.out.println(e);
        }

    }

    public void clearCachedAuthorizationInfo(String principal) {
        System.out.println("######");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();

        try {
            System.out.println("keys:" + userRealm.getAuthorizationCache().keys());
            userRealm.getAuthorizationCache().remove(userRealm.getAuthenticationCache().get(principal).getPrincipals());
            menuMB.setMenus(null);

            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());
        } catch (Exception e) {
            System.out.println("清除权限失败:" + e);
        }

    }

    public void clearAllCachedAuthorizationInfo() {
        System.out.println("######");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();

        try {
            userRealm.getAuthorizationCache().clear();
            menuMB.setMenus(null);
            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());

        } catch (Exception e) {
            System.out.println("清除权限失败:" + e);
        }

    }

    public void clearCachedAuthenticationInfo(String principal) {
        System.out.println("######");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();

        try {
            userRealm.getAuthenticationCache().remove(principal);
            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());

        } catch (Exception e) {
            System.out.println("清除权限失败:" + e);
        }

    }

    public void clearCachedAllAuthenticationInfo() {
        System.out.println("######");
        RealmSecurityManager securityManager
                = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        JdbcRealm userRealm = (JdbcRealm) securityManager.getRealms().iterator().next();

        try {
            userRealm.getAuthenticationCache().clear();
            //userRealm.getAuthenticationCache().remove(SecurityUtils.getSubject().getPrincipal());

        } catch (Exception e) {
            System.out.println("清除权限失败:" + e);
        }

    }

    public void logintest() throws IOException, ServletException {
        try {

            token = new UsernamePasswordToken("1", "888888");

            subject = SecurityUtils.getSubject();
            subject.login(token);

        } catch (Exception e) {

            log.trace("ceshi" + username);
            System.out.println("ShiroMB.login=" + e.toString());
            System.out.println("ShiroMB.username=" + username);
            System.out.println("ShiroMB.pw=" + password);
            System.out.println("ShiroMB.token=" + token);

        }
    }

    public String getLoginid() {
        return subject.getPrincipal().toString();

    }

    public void checkPermission(String permission) {
        if (this.getSubject().isPermitted(permission)) {
        } else {
            throw new org.apache.shiro.authz.UnauthorizedException();
        }
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

}
